home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / sipp / libsipp / objects.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-03  |  18.4 KB  |  780 lines

  1. /**
  2.  ** sipp - SImple Polygon Processor
  3.  **
  4.  **  A general 3d graphic package
  5.  **
  6.  **  Copyright Equivalent Software HB  1992
  7.  **
  8.  ** This program is free software; you can redistribute it and/or modify
  9.  ** it under the terms of the GNU General Public License as published by
  10.  ** the Free Software Foundation; either version 1, or any later version.
  11.  ** This program is distributed in the hope that it will be useful,
  12.  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  ** GNU General Public License for more details.
  15.  ** You can receive a copy of the GNU General Public License from the
  16.  ** Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  **/
  18.  
  19. /**
  20.  ** objects.c - Functions that handles object and surface creation
  21.  **             and the object hierarchies and the object database.
  22.  **/
  23.  
  24. #include <stdio.h>
  25.  
  26. #include <objects.h>
  27. #include <sipp.h>
  28. #include <smalloc.h>
  29.  
  30.  
  31. Object              *sipp_world;      /* The world that is rendered */
  32.  
  33. static Vertex       *vertex_tree;     /* Vertex tree for current object. */
  34. static Vertex_ref   *vertex_stack;    /* Vertex stack for current polygon. */
  35. static int           nvertices;       /* Number of vertices on the stack */
  36. static Vertex_ref   *vstack_bottom;   /* Last entry in vertex stack. */
  37. static Polygon      *poly_stack;      /* Polygon stack for current object. */
  38. static int           first_vertex;    /* Used when determining if we are   */
  39.                                       /* installing the first vertex in an */
  40.                                       /* object. *Not* a boolean!          */
  41. static double        dist_limit;      /* Minimal distance between two      */
  42.                                       /* vertices without them being       */
  43.                                       /* considered to be the same vertex. */
  44.  
  45.  
  46.  
  47. /*
  48.  * Search for a vertex in a vertex tree. Vertices are asumed
  49.  * to be equal if they differ less than dist_limit in all directions.
  50.  *
  51.  * If the vertex is not found, install it in the tree.
  52.  */
  53. static Vertex *
  54. vertex_lookup(pos, texture, p)
  55.     Vector  *pos;
  56.     Vector  *texture;
  57.     Vertex **p;
  58. {
  59.     Vector dist;
  60.  
  61.     if (*p == NULL) {
  62.         *p = (Vertex *)smalloc(sizeof(Vertex));
  63.         (*p)->pos = *pos;
  64.         (*p)->texture = *texture;
  65.         MakeVector((*p)->normal, 0.0, 0.0, 0.0);
  66.         (*p)->big = NULL;
  67.         (*p)->sml = NULL;
  68.         return *p;
  69.     } else {
  70.         VecSub(dist, *pos, (*p)->pos);
  71.         if (dist.x > dist_limit) {
  72.             return (vertex_lookup(pos, texture, &((*p)->big)));
  73.         } else if (dist.x < -dist_limit) {
  74.             return (vertex_lookup(pos, texture, &((*p)->sml)));
  75.         } else if (dist.y > dist_limit) {
  76.             return (vertex_lookup(pos, texture, &((*p)->big)));
  77.         } else if (dist.y < -dist_limit) {
  78.             return (vertex_lookup(pos, texture, &((*p)->sml)));
  79.         } else if (dist.z > dist_limit) {
  80.             return (vertex_lookup(pos, texture, &((*p)->big)));
  81.         } else if (dist.z < -dist_limit) {
  82.             return (vertex_lookup(pos, texture, &((*p)->sml)));
  83.         } else {
  84.             VecSub(dist, *texture, (*p)->texture);
  85.             if (dist.x > dist_limit) {
  86.                 return (vertex_lookup(pos, texture, &((*p)->big)));
  87.             } else if (dist.x < -dist_limit) {
  88.                 return (vertex_lookup(pos, texture, &((*p)->sml)));
  89.             } else if (dist.y > dist_limit) {
  90.                 return (vertex_lookup(pos, texture, &((*p)->big)));
  91.             } else if (dist.y < -dist_limit) {
  92.                 return (vertex_lookup(pos, texture, &((*p)->sml)));
  93.             } else if (dist.z > dist_limit) {
  94.                 return (vertex_lookup(pos, texture, &((*p)->big)));
  95.             } else if (dist.z < -dist_limit) {
  96.                 return (vertex_lookup(pos, texture, &((*p)->sml)));
  97.             } else {
  98.                 return *p;
  99.             }
  100.         }
  101.     }
  102. }
  103.  
  104.  
  105.  
  106. /*
  107.  * Push a vertex on the vertex stack (without texture coordinates).
  108.  */
  109. void
  110. vertex_push(x, y, z)
  111.     double  x, y, z;
  112. {
  113.     vertex_tx_push(x, y, z, (double)0.0, (double)0.0, (double)0.0);
  114. }
  115.  
  116.  
  117.  
  118. /*
  119.  * Push a vertex on the vertex stack (with texture coordinates).
  120.  */
  121. void
  122. vertex_tx_push(x, y, z, u, v, w)
  123.     double  x, y, z, u, v, w;
  124. {
  125.     Vector      pos;
  126.     Vector      texture;
  127.     Vertex_ref *vref;
  128.  
  129.     MakeVector(pos, x, y, z);
  130.     MakeVector(texture, u, v, w);
  131.  
  132.    /* 
  133.     * To get a reasonable dist_limit we use the following "heuristic" 
  134.     * value:
  135.     * The distance between the first two vertices installed in
  136.     * the surface, multiplied by the magic number 1e-10, unless
  137.     * they are the same vertex. In that case 1e-10 is used until
  138.     * we get a vertex that differs from the first.
  139.     */
  140.     if (!first_vertex) {
  141.         first_vertex++;
  142.     } else if (first_vertex == 1) {
  143.         dist_limit = sqrt((x - vertex_tree->pos.x) * (x - vertex_tree->pos.x)
  144.                         + (y - vertex_tree->pos.y) * (y - vertex_tree->pos.y)
  145.                         + (z - vertex_tree->pos.z) * (z - vertex_tree->pos.z))
  146.                    * 1e-10;                      /* Magic!!! */
  147.         if (dist_limit != 0.0)
  148.             first_vertex++;
  149.         else
  150.             dist_limit = 1e-10;                  /* More Magic */
  151.     }
  152.     vref = (Vertex_ref *)smalloc(sizeof(Vertex_ref));
  153.     if (vertex_stack == NULL) {
  154.         vertex_stack = vref;
  155.     } else {
  156.         vstack_bottom->next = vref;
  157.     }
  158.     vstack_bottom = vref;
  159.     vref->vertex = vertex_lookup(&pos, &texture, &vertex_tree);
  160.     vref->next = NULL;
  161.     nvertices++;
  162. }
  163.  
  164.  
  165.  
  166. /*
  167.  * Push a polygon on the polygon stack. Empty the vertex stack afterwards.
  168.  */
  169. void
  170. polygon_push()
  171. {
  172.     Polygon    *polyref;
  173.     Vertex_ref *vref;
  174.     int         i;
  175.  
  176.     if (vertex_stack != NULL) {
  177.         polyref = (Polygon *)smalloc(sizeof(Polygon));
  178.         polyref->vertex = (Vertex **)smalloc(nvertices * sizeof(Vertex *));
  179.         for (i = 0; i < nvertices; i++) {
  180.             polyref->vertex[i] = vertex_stack->vertex;
  181.             vref = vertex_stack;
  182.             vertex_stack = vertex_stack->next;
  183.             sfree(vref);
  184.         }
  185.         polyref->nvertices = nvertices;
  186.         nvertices = 0;
  187.         polyref->backface = 0;
  188.         polyref->next = poly_stack;
  189.         poly_stack = polyref;
  190.     }
  191. }
  192.  
  193.  
  194.  
  195. /*
  196.  * Create a surface of all polygons in the polygon stack.
  197.  * Empty the polygon stack afterwards.
  198.  */
  199. Surface *
  200. surface_create(surf_desc, shader)
  201.     void   *surf_desc;
  202.     Shader *shader;
  203. {
  204.     Surface *surfref;
  205.     Polygon *polyref;
  206.     int      i;
  207.     
  208.     if (poly_stack != NULL) {
  209.         surfref = (Surface *)smalloc(sizeof(Surface));
  210.         surfref->vertices = vertex_tree;
  211.         surfref->polygons = poly_stack;
  212.         surfref->surface = surf_desc;
  213.         surfref->shader = shader;
  214.         surfref->ref_count = 0;
  215.         surfref->next = NULL;
  216.         vertex_tree = NULL;
  217.         poly_stack = NULL;
  218.         first_vertex = 0;
  219.         return surfref;
  220.     } else
  221.         return NULL;
  222. }
  223.  
  224.  
  225.  
  226. /*
  227.  * Create a surface to be shaded with the simple shader.
  228.  */
  229. Surface *
  230. surface_basic_create(ambient, red, grn, blu, specular, c3, 
  231.              opred, opgrn, opblu)
  232.     double   ambient;
  233.     double   red, grn, blu;
  234.     double   specular;
  235.     double   c3;
  236.     double   opred, opgrn, opblu;
  237. {
  238.     Surf_desc *surf_desc;
  239.  
  240.     surf_desc = (Surf_desc *)smalloc(sizeof(Surf_desc));
  241.     surf_desc->ambient = ambient;
  242.     surf_desc->color.red = red;
  243.     surf_desc->color.grn = grn;
  244.     surf_desc->color.blu = blu;
  245.     surf_desc->specular = specular;
  246.     surf_desc->c3 = c3;
  247.     surf_desc->opacity.red = opred;
  248.     surf_desc->opacity.grn = opgrn;
  249.     surf_desc->opacity.blu = opblu;
  250.  
  251.     return surface_create(surf_desc, basic_shader);
  252. }
  253.  
  254.  
  255.  
  256. /*
  257.  * Set SURFACE to be shaded with the shading function SHADER
  258.  * using the surface description SURF_DESC.
  259.  */
  260. void
  261. surface_set_shader(surface, surf_desc, shader)
  262.     Surface *surface;
  263.     void    *surf_desc;
  264.     Shader  *shader;
  265. {
  266.     
  267.     if (surface != NULL) {
  268.         surface->surface = surf_desc;
  269.         surface->shader = shader;
  270.     }
  271. }
  272.  
  273.  
  274.  
  275. /*
  276.  * Set SURFACE to be shaded with the simple shader.
  277.  */
  278. void
  279. surface_basic_shader(surface, ambient, red, grn, blu, specular, c3, 
  280.              opred, opgrn, opblu)
  281.     Surface   *surface;
  282.     double     ambient;
  283.     double     red, grn, blu;
  284.     double     specular;
  285.     double     c3;
  286.     double     opred, opgrn, opblu;
  287. {
  288.     Surf_desc *surf_desc;
  289.  
  290.     surf_desc = (Surf_desc *)smalloc(sizeof(Surf_desc));
  291.     surf_desc->ambient = ambient;
  292.     surf_desc->color.red = red;
  293.     surf_desc->color.grn = grn;
  294.     surf_desc->color.blu = blu;
  295.     surf_desc->specular = specular;
  296.     surf_desc->c3 = c3;
  297.     surf_desc->opacity.red = opred;
  298.     surf_desc->opacity.grn = opgrn;
  299.     surf_desc->opacity.blu = opblu;
  300.     surface_set_shader(surface, surf_desc, basic_shader);
  301. }
  302.  
  303.  
  304.  
  305. /*
  306.  * Copy a vertex tree.
  307.  */
  308. static Vertex *
  309. copy_vertices(vp)
  310.     Vertex *vp;
  311. {
  312.     Vertex *tmp;
  313.  
  314.     if (vp == NULL)
  315.         return NULL;
  316.     tmp = (Vertex *)smalloc(sizeof(Vertex));
  317.     *tmp = *vp;
  318.     tmp->big = copy_vertices(vp->big);
  319.     tmp->sml = copy_vertices(vp->sml);
  320.     return tmp;
  321. }
  322.  
  323.  
  324.  
  325. /*
  326.  * Copy a list of polygons.
  327.  */
  328. static Polygon *
  329. copy_polygons(pp, surface)
  330.     Polygon *pp;
  331.     Surface *surface;
  332. {
  333.     Polygon *tmp;
  334.     int      i;
  335.  
  336.     if (pp == NULL)
  337.         return NULL;
  338.     tmp = (Polygon *)smalloc(sizeof(Polygon));
  339.     tmp->nvertices = pp->nvertices;
  340.     tmp->vertex = (Vertex **)smalloc(tmp->nvertices * sizeof(Vertex *));
  341.     for (i = 0; i < tmp->nvertices; i++) {
  342.         tmp->vertex[i] = vertex_lookup(&pp->vertex[i]->pos, 
  343.                                        &pp->vertex[i]->texture,
  344.                                        &surface->vertices);
  345.     }
  346.     tmp->next = copy_polygons(pp->next, surface);
  347.     return tmp;
  348. }
  349.  
  350.  
  351.  
  352. /*
  353.  * Copy a list of surfaces. All polygons and vertices are copied but
  354.  * the shader and surface descriptions are the same as in the
  355.  * original surfaces.
  356.  */
  357. static Surface *
  358. surface_copy(surface)
  359.     Surface  *surface;
  360. {
  361.     Surface  *newsurf;
  362.  
  363.     if (surface != NULL) {
  364.         newsurf = (Surface *)smalloc(sizeof(Surface));
  365.         if (newsurf == NULL) {
  366.             return NULL;
  367.         }
  368.         memcpy(newsurf, surface, sizeof(Surface));
  369.         newsurf->vertices = copy_vertices(surface->vertices);
  370.         newsurf->polygons = copy_polygons(surface->polygons, newsurf);
  371.         newsurf->ref_count = 1;
  372.         newsurf->next = surface_copy(surface->next);
  373.         return newsurf;
  374.     } else {
  375.         return NULL;
  376.     }
  377. }
  378.  
  379.  
  380.  
  381. /*
  382.  * Delete a vertex tree.
  383.  */
  384. static void
  385. delete_vertices(vtree)
  386.     Vertex **vtree;
  387. {
  388.     if (*vtree != NULL) {
  389.         delete_vertices(&((*vtree)->big));
  390.         delete_vertices(&((*vtree)->sml));
  391.         sfree(*vtree);
  392.         *vtree = NULL;
  393.     }
  394. }
  395.  
  396.  
  397.  
  398. /*
  399.  * Delete a surface list.
  400.  */
  401. static void
  402. surface_delete(surface)
  403.     Surface *surface;
  404. {
  405.     Polygon    *polyref1, *polyref2;
  406.  
  407.     if (surface != NULL) {
  408.         if (--surface->ref_count == 0) {
  409.             if (surface->next != NULL) {
  410.                 surface_delete(surface->next);
  411.             }
  412.             polyref2 = surface->polygons;
  413.             while (polyref2 != NULL) {
  414.                 sfree(polyref2->vertex);
  415.                 polyref1 = polyref2;
  416.                 polyref2 = polyref2->next;
  417.                 sfree(polyref1);
  418.             }
  419.             delete_vertices(&(surface->vertices));
  420.             sfree(surface);
  421.         }
  422.     }
  423. }
  424.  
  425.  
  426.  
  427. /*
  428.  * Create an empty object. 
  429.  */
  430. Object *
  431. object_create()
  432. {
  433.     Object *obj;
  434.  
  435.     obj = (Object *)smalloc(sizeof(Object));
  436.     obj->surfaces = NULL;
  437.     obj->sub_obj = NULL;
  438.     MatCopy(&obj->transf, &ident_matrix);
  439.     obj->ref_count = 0;
  440.     obj->next = NULL;
  441.  
  442.     return obj;
  443. }
  444.  
  445.  
  446.  
  447. /*
  448.  * Copy the top object in an object hierarchy.
  449.  * The new object will reference the same
  450.  * subobjects and surfaces as the original object.
  451.  * if REF_COUNT_UPDATE is true, the reference counts
  452.  * in the surfaces and subobjects will be incremented.
  453.  */
  454. static Object *
  455. object_copy(object, ref_count_update)
  456.     Object *object;
  457.     bool    ref_count_update;
  458. {
  459.     Object *newobj;
  460.  
  461.     if (object == NULL) {
  462.         return NULL;
  463.     }
  464.  
  465.     if ((newobj = (Object *)smalloc(sizeof(Object))) != NULL) {
  466.         memcpy(newobj, object, sizeof(Object));
  467.         if (ref_count_update) {
  468.             if (newobj->sub_obj != NULL) {
  469.                 newobj->sub_obj->ref_count++;
  470.             }
  471.             if (newobj->surfaces != NULL) {
  472.                 newobj->surfaces->ref_count++;
  473.             }
  474.         }
  475.         MatCopy(&newobj->transf, &ident_matrix);
  476.         newobj->ref_count = 0;
  477.         newobj->next = NULL;
  478.     }
  479.  
  480.     return newobj;
  481. }
  482.  
  483.  
  484.  
  485. /*
  486.  * Copy a list of objects. If SURF_COPY is true
  487.  * the surfaces in the objects will be copied too.
  488.  */
  489. static Object *
  490. object_list_copy(object, surf_copy)
  491.     Object *object;
  492.     bool    surf_copy;
  493. {
  494.     Object *newobj;
  495.  
  496.     if (object == NULL) {
  497.         return NULL;
  498.     }
  499.  
  500.     if ((newobj = (Object *)smalloc(sizeof(Object))) != NULL) {
  501.         memcpy(newobj, object, sizeof(Object));
  502.         newobj->ref_count = 0;
  503.     } else {
  504.         return NULL;
  505.     }
  506.  
  507.     if (surf_copy) {
  508.         newobj->surfaces = surface_copy(object->surfaces);
  509.     } else if (newobj->surfaces != NULL){
  510.         newobj->surfaces->ref_count++;
  511.     }
  512.  
  513.     newobj->sub_obj = object_list_copy(object->sub_obj, surf_copy);
  514.     if (newobj->sub_obj != NULL) {
  515.         newobj->sub_obj->ref_count++;
  516.     }
  517.     newobj->next = object_list_copy(object->next, surf_copy);
  518.     if (newobj->next != NULL) {
  519.         newobj->next->ref_count++;
  520.     }
  521.  
  522.     return newobj;
  523. }
  524.     
  525.  
  526.  
  527. /*
  528.  * Copy the top node of an object hierarchy. The
  529.  * subobjects and surface references will be the
  530.  * same as in the original.
  531.  */
  532. Object *
  533. object_instance(obj)
  534.     Object *obj;
  535. {
  536.     return object_copy(obj, TRUE);
  537. }
  538.  
  539.  
  540.  
  541. /*
  542.  * Copy an object hierarchy. The objects in
  543.  * the new hierarchy will reference the same
  544.  * surfaces as the object in
  545.  * the old hierarchy, but all object nodes
  546.  * will be duplicated.
  547.  */
  548. Object *
  549. object_dup(object)
  550.     Object *object;
  551. {
  552.     Object *newobj;
  553.  
  554.     if ((newobj = object_copy(object, FALSE)) == NULL) {
  555.         return NULL;
  556.     }
  557.  
  558.     newobj->sub_obj = object_list_copy(object->sub_obj, FALSE);
  559.     newobj->next = NULL;
  560.  
  561.     return newobj;
  562. }
  563.  
  564.  
  565.  
  566. /*
  567.  * Copy an object hierarchy. All object nodes
  568.  * and surfaces in the old hierarchy
  569.  * will be duplicated.
  570.  */
  571. Object *
  572. object_deep_dup(object)
  573.     Object *object;
  574. {
  575.     Object *newobj;
  576.  
  577.     if ((newobj = object_copy(object, FALSE)) == NULL) {
  578.         return NULL;
  579.     }
  580.  
  581.     newobj->surfaces = surface_copy(object->surfaces);
  582.     newobj->sub_obj = object_list_copy(object->sub_obj, TRUE);
  583.     newobj->next = NULL;
  584.  
  585.     return newobj;
  586. }
  587.  
  588.  
  589.  
  590. /*
  591.  * Recursively delete an object hierarchy. Reference
  592.  * counts are decremented and if the result is zero
  593.  * the recursion continues and the memory used is freed.
  594.  */
  595. static void
  596. r_object_delete(object)
  597.     Object * object;
  598. {
  599.     if (object != NULL) {
  600.         if (--object->ref_count == 0) {
  601.             surface_delete(object->surfaces);
  602.             r_object_delete(object->sub_obj);
  603.             r_object_delete(object->next);
  604.             sfree(object);
  605.         }
  606.     }
  607. }
  608.  
  609.  
  610.  
  611. /*
  612.  * Delete an object hierarchy. This is only possible to do on
  613.  * a top level object in order to avoid dangeling references.
  614.  * Don't allow deletion of the world either...
  615.  */
  616. void
  617. object_delete(object)
  618.     Object * object;
  619. {
  620.     if (object != NULL && object != sipp_world) {
  621.         if (object->ref_count == 0) {         /* Is it a top level object? */
  622.             surface_delete(object->surfaces);
  623.             r_object_delete(object->sub_obj);
  624.             r_object_delete(object->next);
  625.             sfree(object);
  626.         }
  627.     }
  628. }
  629.  
  630.  
  631.  
  632. /*
  633.  * Remove SUBOBJ as a subobject in OBJECT. SUBOBJ is only
  634.  * removed from the list of subojects in OBJECT. If the
  635.  * memory it uses should be freed, object_delete() must
  636.  * be used.
  637.  */
  638. void
  639. object_sub_subobj(object, subobj)
  640.     Object *object, *subobj;
  641. {
  642.     Object *oref1;
  643.     Object *oref2;
  644.  
  645.     if (object == NULL || subobj == NULL || object->sub_obj == NULL) {
  646.         return;
  647.     }
  648.  
  649.     if (object->sub_obj == subobj) {
  650.         object->sub_obj = subobj->next;
  651.     } else {
  652.         oref1 = object->sub_obj;
  653.         oref2 = oref1->next;
  654.         while (oref2 != NULL && oref2 != subobj) {
  655.             oref1 = oref2;
  656.             oref2 = oref2->next;
  657.         }
  658.         if (oref2 == subobj) {
  659.             oref1->next = oref2->next;
  660.         }
  661.     }
  662.  
  663.     subobj->ref_count--;
  664. }
  665.  
  666.  
  667.  
  668. /*
  669.  * Add SUBOBJ as a subobject in OBJECT. SUBOBJ is appended
  670.  * on the *end* of OBJECT's subobject list, 
  671.  * so that if SUBOBJ, for some obscure reason, 
  672.  * were the head of an object list, we don't loose
  673.  * the rest of that list. 
  674.  * Remove SUBOBJ from the rendering database since it is no
  675.  * longer a root object in an hierarchy.
  676.  */
  677. void
  678. object_add_subobj(object, subobj)
  679.     Object *object, *subobj;
  680. {
  681.     Object *oref;
  682.  
  683.     if (object == NULL || subobj == NULL) {
  684.         return;
  685.     }
  686.  
  687.     if (object->sub_obj == NULL) {
  688.         object->sub_obj = subobj;
  689.     } else {
  690.         oref = object->sub_obj;
  691.         while (oref->next != NULL) {
  692.             oref = oref->next;
  693.         }
  694.         oref->next = subobj;
  695.     }
  696.  
  697.     subobj->ref_count++;
  698. }
  699.  
  700.  
  701.  
  702. /*
  703.  * Remove SURFACE as a surface in OBJECT.
  704.  */
  705. void
  706. object_sub_surface(object, surface)
  707.     Object   *object;
  708.     Surface  *surface;
  709. {
  710.     Surface *sref1;
  711.     Surface *sref2;
  712.  
  713.     if (object == NULL || surface == NULL || object->surfaces == NULL) {
  714.         return;
  715.     }
  716.  
  717.     if (object->surfaces == surface) {
  718.         object->surfaces = surface->next;
  719.     } else {
  720.         sref1 = object->surfaces;
  721.         sref2 = sref1->next;
  722.         while (sref2 != NULL && sref2 != surface) {
  723.             sref1 = sref2;
  724.             sref2 = sref2->next;
  725.         }
  726.         if (sref2 == surface) {
  727.             sref1->next = sref2->next;
  728.         }
  729.     }
  730.  
  731.     surface->ref_count--;
  732. }
  733.  
  734.  
  735.  
  736. /*
  737.  * Add SURFACE to the list of surfaces belonging
  738.  * to OBJECT. SURFACE is appended on the *end* of the
  739.  * list for the same reasons as in object_add_subobj.
  740.  */
  741. void
  742. object_add_surface(object, surface)
  743.     Object  *object;
  744.     Surface *surface;
  745. {
  746.     Surface *sref;
  747.  
  748.     if (object == NULL || surface == NULL) {
  749.         return;
  750.     }
  751.  
  752.     if (object->surfaces == NULL) {
  753.         object->surfaces = surface;
  754.     } else {
  755.         sref = object->surfaces;
  756.         while (sref->next != NULL) {
  757.             sref = sref->next;
  758.         }
  759.         sref->next = surface;
  760.     }
  761.  
  762.     surface->ref_count++;
  763. }
  764.     
  765.     
  766.     
  767. /*
  768.  * Initialize the data structures.
  769.  */
  770. void
  771. objects_init()
  772. {
  773.     vertex_tree    = NULL;
  774.     vertex_stack   = NULL;
  775.     nvertices      = 0;
  776.     first_vertex   = 0;
  777.     poly_stack     = NULL;
  778.     sipp_world     = object_create();
  779. }
  780.